<!-- 单建筑分层 -->
<template>
  <div>
  </div>
</template>

<script setup>
import * as d3 from 'd3-geo'
import * as turf from '@turf/turf'
import api from '../../api/geoserver'
import { THREE } from 'threebox-plugin'
import { disposeRoomData } from '../../utils/roomanimate.js'
import { TWEEN } from '../../../public/lib/tween.module.min.js'
import { ref, reactive, onMounted, getCurrentInstance } from 'vue'

const map = getCurrentInstance().proxy.$root.$map,
  path = import.meta.env.VITE_APP_PATH

const property = ref(false)
const obj = reactive({
  name: 'a',
  id: '234353'
})
const switchCenter = [115.61602530954485, 34.432852118706904]
// 墨卡托投影转换
const projection = d3
  .geoMercator()
  .center(switchCenter)
  .scale(5600000)
  .translate([0, 0])

let molayersData, schoolInfo, sslRoomData, sslWallData, ssFloorData

onMounted(() => {
  console.log('分模块中')
  // loadLayerJson()
})

// 加载配置文件中图层信息
async function loadLayerJson() {

  const parameter = {
    service: 'WFS',
    version: '1.0.0',
    request: 'GetFeature',
    typeName: 'zzdx:room',
    maxFeatures: '10000',
    outputFormat: 'application/json'
  }
  const roomData = await api.getLayerData('zzdx', parameter).catch((err) => err)
  sslRoomData = disposeData(roomData)

  // 获取房间墙数据
  parameter.typeName = 'zzdx:indoorwall'
  const wallData = await api.getLayerData('zzdx', parameter).catch((err) => err)
  sslWallData = disposeData(wallData)

  // 获取楼层地板数据
  parameter.typeName = 'zzdx:infloor'
  const floorData = await api.getLayerData('zzdx', parameter).catch((err) => err)
  ssFloorData = disposeData(floorData)
  // const building = createWallFloorMap(sslWallData, sslRoomData, ssFloorData)

  // molayersData = layerJson.data
  setTimeout(() => {
    console.log('建筑信息', sslRoomData, ssFloorData)
    addChartletLayer()
  }, 100)
}

// 处理数据--- 找室内楼id
function disposeData(data) {
  const features = []
  for (const feature of data.features) {
    if (feature.properties.mapid?.includes('01168')) {
      features.push(feature)
    }
  }
  return features
}

// 筛选当前数组中有无当前对象
function arrayQueryObject(arr, id) {
  const ishave = arr.some((item) => {
    if (item === id) {
      return true
    }
  })
  return ishave
}

// 将房间地板、楼层地板、墙按楼层打包
function createWallFloorMap(wallJson, roomJson, floorJson) {
  console.log('墙，房间，楼板', wallJson, roomJson, floorJson)
  // 建一个空对象存放对象
  const building = new THREE.Object3D()
  const floorNum = []
  const floors = []
  // 需要过滤有几层楼
  for (const feature of wallJson) {
    const isexis = arrayQueryObject(floorNum, feature.properties.floor)
    if (!isexis) {
      floorNum.push(feature.properties.floor)
    }
  }
  // console.log('楼层数', floorNum)
  for (let i = 0; i < floorNum.length; i++) {
    floors.push(new THREE.Object3D())
  }
  // 加载墙json数据
  wallJson.forEach((elem) => {
    // 定一个省份3D对象
    const province = new THREE.Object3D()
    // 每个的 坐标 数组
    const coordinates = elem.geometry.coordinates
    // 当前楼层
    const floor = parseInt(elem.properties.floor) - 1
    // 循环坐标数组
    coordinates.forEach((multiPolygon) => {

      multiPolygon.forEach((polygon) => {
        const shape = new THREE.Shape()
        const lineMaterial = new THREE.LineBasicMaterial({ color: 'white' })
        const lineGeometry = new THREE.BufferGeometry()
        const linePoints = []
        for (let i = 0; i < polygon.length; i++) {
          // console.log('multiPolygon==>', polygon)
          const [x, y] = projection(polygon[i])
          // console.log('multiPolygon==>', x, y)
          if (i === 0) {
            shape.moveTo(x, -y)
          }
          shape.lineTo(x, -y)
          linePoints.push(new THREE.Vector3(x, -y, 5.02))
        }
        // console.log('linePoints============', linePoints)
        lineGeometry.setFromPoints(linePoints)

        const extrudeSettings = {
          depth: 5,
          bevelEnabled: false
        }

        const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings)
        const material = new THREE.MeshBasicMaterial({
          color: '#12619f',
          transparent: true,
          opacity: 1
        })
        // new THREE.TextureLoader().load(path + 'img/jiantou1.png', (texture) => {
        //   texture.wrapS = texture.wrapT = THREE.RepeatWrapping
        // texture.repeat.set(50, 1) //重复产生N个相同贴图 产生N行
        // texture.offset.set(0.5, 0.5)
        const material1 = new THREE.MeshBasicMaterial({
          color: '#3991d3',
          transparent: true,
          opacity: 0.6
          // map: texture,
        })

        const mesh = new THREE.Mesh(geometry, [material, material1])
        mesh.floor = floor + 1
        const line = new THREE.Line(lineGeometry, lineMaterial)
        mesh.rotateX(29.84)
        line.rotateX(29.84)
        mesh.translateZ(floor * 6)
        line.translateZ(floor * 6)

        province.add(mesh)
        // })
        // province.add(line)
      })
    })
    // 将geo的属性放到省份模型中
    province.properties = elem.properties
    province.floor = floor + 1
    if (elem.properties.contorid) {
      const [x, y] = projection(elem.properties.contorid)
      province.properties._centroid = [x, y]
    }
    floors[floor].add(province)
  })
  // 加载房间数据
  roomJson.forEach((elem) => {
    // 定一个省份3D对象
    const province = new THREE.Object3D()
    // 每个的 坐标 数组
    const coordinates = elem.geometry.coordinates
    // 当前楼层
    const floor = parseInt(elem.properties.floor) - 1
    // 循环坐标数组
    coordinates.forEach((multiPolygon) => {
      // multiPolygon.forEach((polygon) => {
      const shape = new THREE.Shape()
      const lineMaterial = new THREE.LineBasicMaterial({ color: 'white' })
      const lineGeometry = new THREE.BufferGeometry()
      const linePoints = []
      for (let i = 0; i < multiPolygon.length; i++) {
        const [x, y] = projection(multiPolygon[i])
        if (i === 0) {
          shape.moveTo(x, -y)
        }
        shape.lineTo(x, -y)
        linePoints.push(new THREE.Vector3(x, -y, 0.22))
      }
      lineGeometry.setFromPoints(linePoints)

      const extrudeSettings = {
        depth: 0.2,
        bevelEnabled: false
      }

      const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings)
      const material = new THREE.MeshBasicMaterial({
        color: '#55bae8',
        transparent: true,
        opacity: 1
      })
      const material1 = new THREE.MeshBasicMaterial({
        color: '#102037',
        transparent: true,
        opacity: 0.6
      })
      const mesh = new THREE.Mesh(geometry, [material, material1])

      const line = new THREE.Line(lineGeometry, lineMaterial)
      mesh.rotateX(29.84)
      line.rotateX(29.84)
      mesh.translateZ(floor * 6 + 0.2)
      line.translateZ(floor * 6 + 0.2)
      mesh.floor = floor + 1
      province.add(mesh)
      // province.add(line)
    })
    // })
    // 将geo的属性放到省份模型中
    province.properties = elem.properties
    province.floor = floor + 1
    if (elem.properties.contorid) {
      const [x, y] = projection(elem.properties.contorid)
      province.properties._centroid = [x, y]
    }
    floors[floor].add(province)
  })
  // 加载楼层地板
  floorJson.forEach((elem) => {
    // 定一个省份3D对象
    const province = new THREE.Object3D()
    // 每个的 坐标 数组
    const coordinates = elem.geometry.coordinates[0]
    // 当前楼层
    const floor = parseInt(elem.properties.floor) - 1
    // 循环坐标数组
    coordinates.forEach((multiPolygon) => {

      // multiPolygon.forEach((polygon) => {
      const shape = new THREE.Shape()
      const lineMaterial = new THREE.LineBasicMaterial({ color: 'white' })
      const lineGeometry = new THREE.BufferGeometry()
      const linePoints = []
      for (let i = 0; i < multiPolygon.length; i++) {
        const [x, y] = projection(multiPolygon[i])
        if (i === 0) {
          shape.moveTo(x, -y)
        }
        shape.lineTo(x, -y)
        linePoints.push(new THREE.Vector3(x, -y, 1.02))
      }
      lineGeometry.setFromPoints(linePoints)

      const extrudeSettings = {
        depth: 1,
        bevelEnabled: false
      }

      const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings)
      const material = new THREE.MeshBasicMaterial({
        color: '#194362',
        transparent: true,
        opacity: 1
      })
      const material1 = new THREE.MeshBasicMaterial({
        color: '#0e2435',
        transparent: true,
        opacity: 1
      })
      const mesh = new THREE.Mesh(geometry, [material, material1])
      mesh.floor = floor + 1
      const line = new THREE.Line(lineGeometry, lineMaterial)
      mesh.rotateX(29.84)
      line.rotateX(29.84)
      mesh.translateZ(floor * 6 - 1)
      line.translateZ(floor * 6 - 1)

      province.add(mesh)
      // province.add(line)
    })
    // })
    // 将geo的属性放到省份模型中
    province.properties = elem.properties
    province.floor = floor + 1
    if (elem.properties.contorid) {
      const [x, y] = projection(elem.properties.contorid)
      province.properties._centroid = [x, y]
    }
    floors[floor].add(province)
  })
  for (let i = 0; i < floorNum.length; i++) {
    building.add(floors[i])
  }

  const cube = tb.Object3D({ obj: building, units: 'meters' })
  return cube
}

// 根据配置信息加模型
async function addChartletLayer() {

  map.addLayer({
    id: 'sqsfchartlet_layer',
    type: 'custom',
    renderingMode: '3d',
    onAdd: function (map, mbxContext) {
      // console.log('tb', tb)
      // const sphere = tb.sphere({color: 'red', material: 'MeshToonMaterial'})
      //   .setCoords(switchCenter)
      // sphere.addEventListener('ObjectMouseOver', onObjectMouseOver, false)
      // sphere.addEventListener('ObjectMouseOut', onObjectMouseOut, false)
      // add sphere to the scene
      // tb.add(sphere)
      addBuildings()
      // building.setCoords([switchCenter[0], switchCenter[1], 0])
      // tb.scene.add(building)
    },
    render: function (gl, matrix) {
      tb.update()
    }
  })
  // 将模型图层位置调整到建筑图层前
  // console.log('schoolInfo', schoolInfo)
  // schoolInfo.layers.some((layer) => {
  //   if(layer.name === '校内建筑') {
  //     map.moveLayer(schoolInfo.modelLayerid, layer.layerId)
  //     return true
  //   }
  // })
}
let animateCfg
const province = new THREE.Object3D()
const floors = []
for (let i = 0; i < 8; i++) {
  floors.push(new THREE.Object3D())
}
const building = new THREE.Object3D()

function addBuildings() {

  // 房间数据整理
  sslRoomData.forEach((elem) => {
    // 当前楼层
    const floor = parseInt(elem.properties.floor) - 1
    const material = new THREE.MeshBasicMaterial({
      color: '#55bae8',
      transparent: true,
      opacity: 1
    })
    const material1 = new THREE.MeshBasicMaterial({
      color: '#102037',
      transparent: true,
      opacity: 0.6
    })
    if (elem.geometry && elem.geometry.coordinates) {
      const polygon = turf.polygon(elem?.geometry?.coordinates)
      const center = turf.centerOfMass(polygon).geometry.coordinates

      const extrusion = tb.extrusion({
        coordinates: elem.geometry.coordinates,
        geometryOptions: { curveSegments: 1, bevelEnabled: false, depth: 0.01 },
        materials: [material, material1]
      })
      // extrusion.addTooltip(b.properties.tooltip, true)
      extrusion.setCoords([center[0], center[1], floor * 6 + 0.1])
      extrusion.floor = floor + 1
      floors[floor].add(extrusion)
    }

  })
  // 墙数据整理
  sslWallData.forEach((elem) => {
    // 当前楼层
    const floor = parseInt(elem.properties.floor) - 1
    const material = new THREE.MeshBasicMaterial({
      color: '#12619f',
      transparent: true,
      opacity: 1
    })
    const material1 = new THREE.MeshBasicMaterial({
      color: '#3991d3',
      transparent: true,
      opacity: 0.6
    })
    elem?.geometry?.coordinates.forEach((multiPolygon) => {
      const polygon = turf.polygon(multiPolygon)
      const center = turf.centroid(polygon).geometry.coordinates

      const extrusion = tb.extrusion({
        coordinates: multiPolygon,
        geometryOptions: { curveSegments: 1, bevelEnabled: false, depth: 0.15 },
        materials: [material, material1]
      })
      // extrusion.addTooltip(b.properties.tooltip, true)
      extrusion.setCoords([center[0], center[1], floor * 6])
      extrusion.floor = floor + 1
      floors[floor].add(extrusion)
    })
  })
  // 地板数据整理
  ssFloorData.forEach((elem) => {
    // 当前楼层
    const floor = parseInt(elem.properties.floor) - 1
    const material = new THREE.MeshBasicMaterial({
      color: '#194362',
      transparent: true,
      opacity: 1
    })
    const material1 = new THREE.MeshBasicMaterial({
      color: '#0e2435',
      transparent: true,
      opacity: 1
    })
    elem?.geometry?.coordinates.forEach((multiPolygon) => {
      const polygon = turf.polygon(multiPolygon)
      const center = turf.centerOfMass(polygon).geometry.coordinates

      const extrusion = tb.extrusion({
        coordinates: multiPolygon,
        geometryOptions: { curveSegments: 1, bevelEnabled: false, depth: 0.01 },
        materials: [material, material1]
      })
      // extrusion.addTooltip(b.properties.tooltip, true)
      extrusion.setCoords([center[0], center[1], floor * 6 - 0.1])
      extrusion.floor = floor + 1
      floors[floor].add(extrusion)
    })
  })
  // console.log('floors', floors)
  for(let i = 0; i < floors.length; i++) {
    building.add(floors[i])
  }
  console.log('building', building)
  tb.add(building)
  animateCfg = disposeRoomData(building)
}

function selectFloor(floor) {
  console.log('楼层动画', floor)
  animateCfg.room.accor.go(floor - 1).then()
  // const center = province.children[floor].coordinates
  // province.children[floor].setCoords([center[0], center[1], 100])
  let height = 0
  const timer = setInterval(() => {
    height += 1
    TWEEN.update()
    if (height > 1000) {
      clearInterval(timer)
    }
  }, 10)
}

defineExpose({
  loadLayerJson,
  selectFloor
})

</script>

<style lang='scss' scoped>

</style>